package com.bytemonster.controller;

import cn.hutool.core.util.ObjectUtil;
import com.bytemonster.pojo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Controller
@RequestMapping("sse")
@Slf4j
public class SseController {

    private static final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();

    @GetMapping(value = "connect/{key}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @ResponseBody
    public SseEmitter connect(@PathVariable("key") String key) {
        SseEmitter emitter = new SseEmitter(0L);
        // 注册回调清理资源
        emitter.onCompletion(() -> {
            emitters.remove(key);
            log.info("客服端: {}, SSE 连接完成: {}", key, emitter);
        });
        emitter.onTimeout(() -> {
            emitters.remove(key);
            log.info("客服端: {}, SSE 连接超时: {}", key, emitter);
        });
        emitter.onError(e -> {
            emitters.remove(key);
            log.info("客服端: {}, SSE 连接异常: {}", key, emitter);
        });

        try {
            emitter.send(SseEmitter.event()
                    .name("connect")
                    .data("连接已建立")
                    .id(String.valueOf(System.currentTimeMillis())));
        } catch (IOException e) {
            log.error("发送初始事件失败", e);
            emitter.completeWithError(e);
            return emitter;
        }
        emitters.put(key, emitter);
        log.info("新增 SSE 客服端: {}", key);
        log.info("新增 SSE 订阅，当前订阅数: {}", emitters.size());
        return emitter;
    }

    @GetMapping("sendAll/{message}")
    @ResponseBody
    public R<Boolean> sendAll(@PathVariable("message") String message) {
        Set<String> keys = emitters.keySet();
        for (String key : keys) {
            SseEmitter emitter = emitters.get(key);
            try {
                emitter.send(SseEmitter.event()
                        .name("message")
                        .data(message)
                        .id(String.valueOf(System.currentTimeMillis())));
            } catch (IOException e) {
                emitters.remove(key);
                log.error("发送事件失败", e);
                return R.error(String.format("发送信息: %s 失败",message));
            }
        }
        return R.success(true);
    }


    @GetMapping("sendDesignate/{key}/{message}")
    @ResponseBody
    public R<Boolean> sendDesignate(@PathVariable("key") String key, @PathVariable("message") String message) {
        SseEmitter sseEmitter = emitters.get(key);
        if (ObjectUtil.isNull(sseEmitter)) {
            return R.error("指定客服端不在线");
        }
        try {
            sseEmitter.send(SseEmitter.event()
                    .name("message")
                    .data(message)
                    .id(String.valueOf(System.currentTimeMillis())));
            return R.success(true);
        } catch (IOException e) {
            emitters.remove(key);
            log.error("发送信息失败", e);
            return R.error(String.format("发送信息: %s , 到: %S 失败",message,key));
        }
    }

    @GetMapping("sse-view")
    public String sseView() {
        return "sse-view";
    }

}
